<?php

declare(strict_types=1);

namespace App\Middleware;

use App\Model\Admin;
use App\Model\Permission;
use Hyperf\Contract\SessionInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class AdminAuthMiddleware implements MiddlewareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var SessionInterface
     */
    protected $session;

    /**
     * @var ResponseInterface
     */
    protected $response;

    public function __construct(ContainerInterface $container, SessionInterface $session, \Hyperf\HttpServer\Contract\ResponseInterface $response)
    {
        $this->container = $container;
        $this->session = $session;
        $this->response = $response;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $uri = $this->getUri($request);
        if (substr($uri, 1, 5) !== "admin") return $handler->handle($request);
        if (in_array($uri, ["/admin/login/login","/admin/login/logout"])) return $handler->handle($request);

        // 判断用户是否登录
        if (!$this->session->get("admin") instanceof Admin) {
            return $this->errResponse($request, 9999, "用户未登录", "/admin/login/login");
        }

        // 判断当前登录账户是否有权限
        if (!in_array($uri, Permission::getPermissionsByRoleId($this->session->get("admin")->id))) {
            return $this->errResponse($request, 9999, "用户没权限", "/admin/login/login");
        }

        return $handler->handle($request);
    }

    protected function errResponse($request, $code, $message, $path)
    {
        // 判断是否Ajax
        if (count($request->getHeader("X-Requested-With")) != 0) {
            return $this->response->json([
                "code"    => $code,
                "message" => $message
            ]);
        } else {
            return $this->response->redirect($path);
        }
    }

    protected function getUri($request)
    {
        $uri = explode("/", $request->getUri()->getPath());
        if (isset($uri[4])) unset($uri[4]);
        return implode("/", $uri);
    }
}